/*
 * test_udp.cpp
 *
 *  Created on: Nov 8, 2013
 *      Author: killerg
 */

#include <event2/util.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>


/* Sample UDP client */

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

void fun_cli(const char* saddr) {
    int sockfd=socket(AF_INET, SOCK_DGRAM, 0);

    sockaddr addr;
    int addrlen = sizeof(addr);
    if (evutil_parse_sockaddr_port("0.0.0.0:32000", &addr, &addrlen) < 0) {
        printf("parse addr error: %s\n", evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
        return;
    }

    char sendline[1000];
    while (fgets(sendline, 10000, stdin) != NULL) {
        char recvline[1000];
        sockaddr cliaddr;
        sendto(sockfd, sendline, strlen(sendline), 0, &addr, addrlen);
        int n = recvfrom(sockfd, recvline, 10000, 0, NULL, NULL);
        recvline[n] = 0;
        fputs(recvline, stdout);
    }
}


void fun_svr() {
    int sockfd=socket(AF_INET, SOCK_DGRAM, 0);

    sockaddr addr;
    int addrlen = sizeof(addr);
    if (evutil_parse_sockaddr_port("0.0.0.0:32000", &addr, &addrlen) < 0) {
        printf("parse addr error: %s\n", evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
        return;
    }

    if (bind(sockfd, &addr, addrlen) < 0) {
        printf("bind error: %s\n", evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
        return;
    }

    for (;;) {
        char mesg[1000];
        sockaddr cliaddr;
        uint len = sizeof(cliaddr);
        int n = recvfrom(sockfd, mesg, 1000, 0, &cliaddr, &len);
        sendto(sockfd, mesg, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
        printf("-------------------------------------------------------\n");
        mesg[n] = 0;
        printf("Received the following:\n");
        printf("%s", mesg);
        printf("-------------------------------------------------------\n");
    }
}

#include <thread>



bool test_udp() {
    std::thread thr_svr(fun_svr);
    std::thread thr_cli(fun_cli, "127.0.0.1");

    thr_cli.join();
    thr_svr.join();


    return true;
}
/*
void game_cli() {
    int status = 0;

    while (true) {
        switch (status) {
        // auth
        case 0:
            {
                void* msg = recvfrom();
                if (NULL != msg) {
                    if (needreg) {
                        status = 1;
                    } else if(passwderr) {

                    } else {
                        status = 2;
                    }
                } else {
                    static double timer = 0.0f;
                    timer -= g_clock.delta;
                    if (timer < 0) {
                        timer = 1.0f;
                        sendto();
                    }
                }
            }
            break;
        // reg
        case 1:
            {
                void* msg = recvfrom();
                if (NULL != msg) {
                    if (ok) {
                        status = 0;
                    } else {
                        status = 4;
                    }
                } else {
                    static double timer = 0.0f;
                    timer -= g_clock.delta;
                    if (timer < 0) {
                        timer = 1.0f;
                        sendto();
                    }
                }
            }
            break;
        // svrlist
        case 2:
            {
                void* msg = recvfrom();
                if (NULL != msg) {
                    set_serverlist
                    status = 3;
                } else {
                    static double timer = 0.0f;
                    timer -= g_clock.delta;
                    if (timer < 0) {
                        timer = 1.0f;
                        sendto();
                    }
                }
            }
            break;
        // select
        case 3:
            {
                void* msg = recvfrom();
                if (NULL != msg) {
                    status = 5;
                } else {
                    select a server;

                    static double timer = 0.0f;
                    timer -= g_clock.delta;
                    if (timer < 0) {
                        timer = 1.0f;
                        sendto();
                    }
                }
            }
            break;
        // null
        case 4:
            break;
        // play
        case 5:
            break;
        }
    }
}

void game_svr() {
    while (true) {
        void* msg = recvfrom();
        if (NULL == msg)
            continue;

        entity = find_entity();
        if (NULL == entity) {
            create entity;
        }
        switch (entity.status) {
        case created:
            switch(msg) {
            case auth:
                {
                    if (entity is authed) {
                        sendto authed
                    } else {
                        auth_mgr.auth([](){
                            if (ok) {
                                send authed
                            } else if (passwd err) {
                                send passwd err
                            } eles if (not reg) {
                                send reg
                            }
                        });
                    }
                }
                break;
            case reg:
                {
                    entity.status = reging;
                }
                break;
            }
            break;
        case authing:
            break;
        case reging:
            break;
        case svrlist:
            break;
        case selecting:
            break;
        }
    }
}

*/
